﻿using EnvDTE;
using Microsoft.VisualStudio.VCCodeModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace KinRefactorCompany.RefactorCpp
{
	class NewClassCreater
	{
		public NewClassCreater(string className, Project currentProject)
		{
			CurrentProject = currentProject;
			ClassName = className;

			HeadFileName = className + ".h";
			CppFileName = className + ".cpp";
			HppFileName = className + ".hpp";
			NameSpaceName = StructNameSpaceName();
			ProtectHeaderName = StructProHeaderName();
		}

		private string StructNameSpaceName()
		{
			return CurrentProject.Name;
		}

		private string StructProHeaderName()
		{
			string soluctionName = System.IO.Path.GetFileNameWithoutExtension(CurrentProject.DTE.Solution.FullName);

			string HeadProtectText = "__" + soluctionName + "__" + CurrentProject.Name + "_" + ClassName + "_h_";

			return HeadProtectText;
		}


		private Project CurrentProject;

		private string ClassName;
		private string ProtectHeaderName;
		private string HeadFileName;
		private string HppFileName;
		private string CppFileName;
		private string NameSpaceName;


		internal void Create()
		{
			var CodeManager = CurrentProject.CodeModel as VCCodeModel;
			CodeManager.StartTransaction("FileCreateClassForAllNew");


			//1Step Create The Class With Declaration
			CreateNewClassRoutine();

			//2Step Include Hpp Add Descript The File
			IncludeHppAndDescription();
			

			//3Add The Protect Header
			//CreateNewProtectHeader(HeadFileName);


			CodeManager.CommitTransaction();
		}

		private void IncludeHppAndDescription()
		{
			var CodeManager = CurrentProject.CodeModel as VCCodeModel;
			var Include = CodeManager.AddInclude("\"" + HppFileName + "\"", HeadFileName, -1) as VCCodeInclude;

			string DescriptionText =
@"
/********************************************************************
	日期:		" + DateTime.Now.ToString("yyyy年MM月dd日  dddd    HH:mm:ss") +
@"
	文件:		" + HeadFileName +
@"
	作者:		Kin
	邮箱:		yxwsbobo[at]gmail[dot]com
	说明:		
*********************************************************************/

";

			Include.GetEndPoint(vsCMPart.vsCMPartWholeWithAttributes).CreateEditPoint().Insert("\n\n" + DescriptionText);
		}

		private void CreateNewProtectHeader(string FileName)
		{
			var CodeManager = CurrentProject.CodeModel as VCCodeModel;

			var BeginMacro = CodeManager.AddMacro(ProtectHeaderName, FileName, "", 1) as VCCodeMacro;
			BeginMacro.GetStartPoint(vsCMPart.vsCMPartAttributesWithDelimiter).CreateEditPoint().Insert("#ifndef " + ProtectHeaderName + "\n");

			var EndMacro = CodeManager.AddMacro(ProtectHeaderName + "_END_", FileName, "", -1) as VCCodeMacro;
			EndMacro.GetEndPoint(vsCMPart.vsCMPartWholeWithAttributes).CreateEditPoint().Insert("\n\n#endif  //" + ProtectHeaderName);

		}


		private void CreateNewClassRoutine()
		{
			var CodeManager = CurrentProject.CodeModel as VCCodeModel;

			//1Step Create The Class;
			var HeadNameSpace = CodeManager.AddNamespace(NameSpaceName, HeadFileName, -1) as VCCodeNamespace;

			var TheClass = HeadNameSpace.AddClass(ClassName) as VCCodeClass;
			TheClass.AddFunction(ClassName, vsCMFunction.vsCMFunctionConstructor, "", -1, vsCMAccess.vsCMAccessPublic, CppFileName);
			var Destructor = TheClass.AddFunction("~" + ClassName, vsCMFunction.vsCMFunctionDestructor, "", -1, vsCMAccess.vsCMAccessPublic, CppFileName) as VCCodeFunction;
			Destructor.IsVirtual = true;



			//2Step Create The Declaration
			var HppNameSpace = CodeManager.AddNamespace(NameSpaceName, HppFileName, -1) as VCCodeNamespace;
			HppNameSpace.AddUsingAlias(TheClass.Name, TheClass.DeclarationText, -1);
			HppNameSpace.AddUsingAlias("P" + TheClass.Name, TheClass.Name + " *", -1);
			HppNameSpace.AddUsingAlias("PC" + TheClass.Name, "const " + TheClass.Name + " *", -1);
			HppNameSpace.AddUsingAlias("R" + TheClass.Name, TheClass.Name + " &", -1);
			HppNameSpace.AddUsingAlias("RC" + TheClass.Name, "const " + TheClass.Name + " &", -1);


		}
	}
}
